(function (){
	String.prototype.replaceAll = function(s1,s2){ 
		return this.replace(new RegExp(s1,"gm"),s2); 
	}
	Class.$("Damnsingle",{
		_constructor : function (id) { 
			var me = this;
			me.containerID = id;
			me.containerObj = document.getElementById(id);
			me.isFristInit = true;
			me._initGet();
			me._router();

		},
		controller: function (controllers) {
			var me = this;
			me.controllers = controllers;
			if ( me.option.isResponseRoute == true && window.location.hash.substr(1).length > 0 ) { 
 				 me._analyticalRouter(this);
			} else {
				if( me.option.defaultController in me.controllers ) {
					if ( "main" in me.controllers[me.option.defaultController] ){
						me.controllers[me.option.defaultController].main();
					}else{
						throw new Error("Method 'main' is not defined");
					}
				}
			}
		},
		config : function (option){
			var me = this;
			me.option = option;
			me.option.initFn(); 
		},
		L : function (modelName){
			var me = this;
			if ( !me.option.defaultModelDir ) me.option.defaultModelDir = "model" ;
			var tObj = "";
			$.ajax({type:'get',async:false,url:me.option.defaultModelDir + "/" + modelName + ".json?" + Date.parse(new Date()),dataType : 'json',success:function(data,status){
				tObj = data;
			}});
			return tObj[modelName];
		},
		M : function(model,objData){
			var me = this;
			var tData = model;
			for (objName in objData){
				tData = tData.replaceAll("{{ " + objName + " }}" ,objData[objName]);
			}
			return tData;
		},
		T : function(tName,cId) {
			var me = this;
			var toggleAnimationCode = "";
			var fnCallBack = "";

			if ( arguments.length == 1 ) {   
				fnCallBack = function (){};
				cId = me.containerID;
			} else if ( (arguments.length == 2 && typeof cId == "function" )) {  
				fnCallBack = cId;
				cId = me.containerID;
			} else if ( arguments.length == 3 && typeof arguments[2] == "function" ){
				fnCallBack = arguments[2]; 
			} else {
				fnCallBack = function (){};
			}
			if ( me.option.toggleAnimation != 0 ) {
				switch(me.option.toggleAnimation)
				{
					 case 1:
					    toggleAnimationCode = "<div id=\"ds-LoadingAnimation\" class=\"load-container load6\"><div class=\"loader\">Loading...</div></div>";
					  break; 
					default:
				}
				setTimeout(function() { 
					$("#ds-LoadingAnimation").remove();
				},700);
			}
			if ( !me.option.defaultTemplateDir ) me.option.defaultTemplateDir = "template" ;
			if ( tName.indexOf("<") == -1 && me.option.defaultTemplateDir ) {
				$.ajax({type:'get',async:false,url:me.option.defaultTemplateDir + "/" + tName + ".dsg?" + Date.parse(new Date()),success:function(data,status){
					var tData = me.M(data,me.render); 
					Zepto(function($){
						document.getElementById(cId).innerHTML = toggleAnimationCode + tData; 
						var jumpObjs = $("*[ds-jump]");
						for (var i = 0; i < jumpObjs.length; i++) {
							var clickFn = $("*[ds-jump]").eq(i).attr("ds-click");  
							$("*[ds-jump]").eq(i).bind("touchstart" , 
								new Function(
									"return function(){ window.location.href = '" + $("*[ds-jump]").eq(i).attr("ds-jump") + "'; return false;}"
								)()
							);
						}
						var clickObjs = $("*[ds-click]");
						for (var i = 0; i < clickObjs.length; i++) {
							var clickFn = $("*[ds-click]").eq(i).attr("ds-click");  
							$("*[ds-click]").eq(i).bind("click" , 
								new Function(
									"return function(){ " + ((clickFn in me.event) ? "(" + me.event[clickFn] + ")" : "(function (){})") + "(); return false;}"
								)()
							);
						} 
					}); 
				}});
			}else if ( tName.indexOf("<") != -1 ){
				var tData = tName;
				for (objName in me.render){
					tData = tData.replaceAll("{{ " + objName + " }}" ,me.render[objName]);
				}
				Zepto(function($){
					document.getElementById(cId).innerHTML = toggleAnimationCode + tData;
					var jumpObjs = $("*[ds-jump]");
					for (var i = 0; i < jumpObjs.length; i++) {
						var clickFn = $("*[ds-jump]").eq(i).attr("ds-click");  
						$("*[ds-jump]").eq(i).bind("touchstart" , 
							new Function(
								"return function(){ window.location.href = '" + $("*[ds-jump]").eq(i).attr("ds-jump") + "'; return false;}"
							)()
						);
					}
					var clickObjs = $("*[ds-click]");
					for (var i = 0; i < clickObjs.length; i++) {
						var clickFn = $("*[ds-click]").eq(i).attr("ds-click");  
						$("*[ds-click]").eq(i).bind("click" , 
							new Function(
								"return function(){ " + ((clickFn in me.event) ? "(" + me.event[clickFn] + ")" : "(function (){})") + "(); return false;}"
							)()
						);
					} 
				}); 
			}
			setTimeout(function(){
				fnCallBack();
			},1); 
		},
		J : function(url){
			window.location.href = url;
		},
		_initGet : function(){
	    	var me = this;
			me.GET = (function(){
			    var url = window.document.location.href.toString();
			    var u = url.split("?");
			    if(typeof(u[1]) == "string"){
			        u = u[1].split("&");
			        var get = {};
			        for(var i in u){
			            var j = u[i].split("=");
			            get[j[0]] = j[1];
			        }
			        return get;
			    } else {
			        return {};
			    }
			})();
	    }, 
		_router : function() {
			var me = this;
			window.onhashchange = function(){
				me._analyticalRouter(me);
			}
		},
		_analyticalRouter : function(me){
			me._initGet();
			me.controllerName = window.location.hash.substr(1); 
			if ( me.controllerName.indexOf("?") != -1 ){
				me.controllerName = me.controllerName.split("?")[0];
			}
			if ( me.controllerName.indexOf("/") != -1 ) {
				me.controllerParameter = me.controllerName.split("/");
				if ( me.controllerParameter.length == 1 ){
					throw new Error("router '" + me.controllerName + "' is Syntax error"); 
				}else if ( me.controllerParameter.length == 2 ) {
					if ( me._coutObjAttr(me.controllers[me.controllerParameter[1]]) >= 1 ) { 
						me.controllers[me.controllerParameter[1]].main();  
						//me.controllers[me.controllerParameter[1]]['main']();
						//console.log(me.controllers[me.controllerParameter[1]]['main']);
					} else {
						throw new Error("The controller '" + me.controllerName + "' is not defined"); 
					}
				}else if ( me.controllerParameter.length == 3 ){

					if ( me.controllerParameter[2] in me.controllers[me.controllerParameter[1]] ) {
						me.controllers[me.controllerParameter[1]][me.controllerParameter[2]]();
					}else{
						throw new Error("Method '" + me.controllerParameter[2] + "' is not defined");
					}
				}else if ( me.controllerParameter.length == 4 && me.controllerParameter[3] =="" ){
					if ( me.controllerParameter[2] in me.controllers[me.controllerParameter[1]] ) {

						me.controllers[me.controllerParameter[1]][me.controllerParameter[2]]();
					}else{
						throw new Error("Method '" + me.controllerParameter[2] + "' is not defined");
					}
				}else{
					throw new Error("router '" + me.controllerName + "' is Syntax error"); 
				}
			}else{
				if ( me.controllerName == ""){
					me.controllers[me.option.defaultController].main();
				}else{
					throw new Error("router '" + me.controllerName + "' is Syntax error"); 
				}
			}
		},
		_coutObjAttr : function(obj){
			var n = 0;
			for(var i in obj){
				n++;
			}
			return n;
	    }, 
	    _s : function(str){
	    	console.log(str);
	    }
	});
})();